首页 > 试题广场 >

最小的K个数

[编程题]最小的K个数
  • 热度指数:1197517 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
数据范围:,数组中每个数的大小
要求:空间复杂度 ,时间复杂度 O(nlogk)

示例1

输入

[4,5,1,6,2,7,3,8],4 

输出

[1,2,3,4]

说明

返回最小的4个数即可,返回[1,3,2,4]也可以        
示例2

输入

[1],0

输出

[]
示例3

输入

[0,1,2,1,2],3

输出

[0,1,1]
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param input int整型一维数组 
# @param k int整型 
# @return int整型一维数组
#
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        for i in range(1, len(input)):
            j = i - 1
            tmp = input[i]
            while j >= 0 and input[j] > tmp:
                input[j+1] = input[j]
                j -= 1
            input[j+1] = tmp
        return input[:k]

发表于 2023-07-02 11:33:39 回复(0)

保留最小k个,应维护容量为k的大顶堆,若超过k个,则立刻pop出最大的数字,最后剩余k个就是最小的

牛客C#没有优先队列,跑来写Python
结果发现Python没有大顶堆,只能使用小顶堆*-1丑陋操作

import heapq
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        max_heap = []
        if k == 0:
            return max_heap

        for num in input:
            #不足k个或更小
            if len(max_heap) < k:
                heapq.heappush(max_heap, -num)
            else:
                heapq.heappushpop(max_heap, -num) # 自动淘汰最大的数字

        return [i * -1 for i in max_heap]
发表于 2023-05-02 21:48:31 回复(0)
# 维护一个k个元素的大顶堆,堆顶元素是k个元素的最大值,每来一个新元素时,判断其与堆顶元素的关系:若新元素比堆顶元素小,那么用该元素替换堆顶元素,同时更新最大堆
class maxHeap(object):
    def __init__(self, k):
        self._stack = []
        self._count = 0
        self.k = k

    def size(self):
        return self._count

    def getAllElement(self):
        return self._stack

    def add(self, x):
        # 先判断当前堆元素是否已满
        if self.size() < self.k:
            self._stack.append(x)
            self._shift_up(self._count)
            self._count += 1
        # 若当前堆元素已满
        else:
            if x < self.peak():
                self._stack[0] = x
                self._shift_down(0)
            
    def peak(self):
        return self._stack[0] if self._stack else None

    # 从最后一个节点开始往上更新
    def _shift_up(self, index):
        parent = (index - 1) >> 1
        while index > 0 and self._stack[index] > self._stack[parent]:
            self._stack[index], self._stack[parent] = self._stack[parent], self._stack[index]
            index = parent
            parent = (index - 1) >> 1

    
    # 从第一个节点开始往下更新 
    def _shift_down(self, index):
        max_child = (index << 1) + 1
        # 先判断一下左右节点哪个更大一些
        if max_child + 1 < self._count and self._stack[max_child + 1] > self._stack[max_child]:
            max_child += 1
        while max_child < self._count and self._stack[index] < self._stack[max_child]:
            self._stack[index], self._stack[max_child] = self._stack[max_child], self._stack[index]
            index = max_child
            max_child = (index << 1) + 1
            if max_child + 1 < self._count and self._stack[max_child + 1] > self._stack[max_child]:
                    max_child += 1


class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        if k <= 0:
            return None
        max_heap = maxHeap(k)
        for num in input:
            max_heap.add(num)

        return max_heap.getAllElement()

发表于 2023-02-28 15:53:48 回复(0)
两种方法:
from queue import PriorityQueue
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        '''solution1'''
#         num = sorted(input)
#         return num[:k]
        '''solution2'''
        pq = PriorityQueue()
        res = []
        for i in input:
            pq.put((i, i))
        for i in range(len(input)):
            res.extend( list(pq.get())[1:] )
        return res[:k]


发表于 2022-09-13 16:09:50 回复(0)
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        if len(input) == 0 or k == 0:
            return []
        a = sorted(input)
        return a[:k]
发表于 2022-09-09 16:42:04 回复(0)
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        if not input: return None
        if k > len(input): return None
        input.sort()
        return input[0:k]

发表于 2022-07-26 21:34:29 回复(0)
先排序再取数
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param input int整型一维数组 
# @param k int整型 
# @return int整型一维数组
#
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        if len(input)>0:
            input.sort()
            if k>0:
                if k<len(input):
                    return input[:k]
                else:
                    return input
            else:
                return []
        else:
            return []


发表于 2022-07-18 21:35:27 回复(0)
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        return sorted(input,reverse=False)[:k]
#我每个题都只会写这样的蠢代码,怎么办兄弟们,有大佬告诉下这样能通过面试笔试嘛
发表于 2022-07-11 16:42:58 回复(0)
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        res = []
        for i in range(k):
            res.append(min(input))
            input.remove(min(input))
        return res
发表于 2022-07-05 11:47:35 回复(0)
1. 排序取前面k个元素。
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        return sorted(input)[:k]
2. 堆排序,因为 0 < val < 1000,  0 < n < 10000。
数据范围比数值还大,所以用堆排序。
初始化1000大小的全为0的数组,然后记录input中每个数出现的次数。
然后从小到大遍历看每个数出现的是否为0,若不是则加入到ans中,注意判断k与当前数字的次数。
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        arr = [0] * (1000 + 5)
        for i in input:
            arr[i] += 1
        ans = []
        for i in range(0, 1005):
            if arr[i]:
                if arr[i] < k:
                    ans += [i] * arr[i]
                    k -= arr[i]
                else:
                    ans += [i] * k
                    break
        return ans



发表于 2022-06-21 10:44:54 回复(0)
快排思想
class Solution:
    def partition(self, a, low, high):
        temp = a[low]
        while low < high:
            while low < high and a[high] > temp:
                high -= 1
            a[low] = a[high]
            while low < high and a[low] <= temp:
                low += 1
            a[high] = a[low]
        a[low] = temp
        return low

    def quick_sort(self, a, low, high, k):
        p =self.partition(a, low, high)
        if p-low+1 == k:
            return a[:p+1]
        elif p-low+1 > k:
            return self.quick_sort(a, low, p-1, k)
        else:
            return self.quick_sort(a, p+1, high, k-(p-low+1))

    def GetLeastNumbers_Solution(self , input_: List[int], k: int) -> List[int]:
        n = len(input_)
        if k > n or n == 0 or k == 0:
            return []
        return self.quick_sort(input_, 0, len(input_)-1, k)

class Solution:
   # 利用堆排序 最小堆  
    def minFixHeap(self,t,i,n):
        # 最小堆调整
        tmp = t[i]
        j = i*2 + 1
        while j < n:
            # 找出左右叶子节点较小值
            if j+1 < n and t[j] > t[j+1]:
                j = j + 1
            # 找出根和叶子节点的最小值
            if tmp > t[j]:
                t[i] = t[j]  # 最小值放在根上
                i = j
                j = i*2 + 1
            else:
                break
        t[i] = tmp

    def GetLeastNumbers_Solution(self, tinput, k):
        lens = len(tinput)
        if k>lens or k <0 or lens ==0:
            return []
        # 从最后一个非叶子节点开始调整,反复调用筛选过程,直到第一个节点,则得到一个堆
        for i in range(lens//2,-1,-1):
            self.minFixHeap(tinput,i,lens)

        res = []
        for i in range(lens-1,lens-k-1,-1):
            res.append(tinput[0])
            # 将最后的叶子节点放到根节点,重新进行最小堆调整
            tinput[0] = tinput[i]  
            self.minFixHeap(tinput,0,i)
        return res
发表于 2022-06-18 15:21:16 回复(0)
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        in_data=sorted(input)
        if k>0:
            return in_data[:k]
        else:
            return []
发表于 2022-06-08 17:31:48 回复(0)
import heapq
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        return heapq.nsmallest(k,input)
发表于 2022-05-01 14:24:35 回复(0)
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        return sorted(input)[:k]

发表于 2022-04-25 15:42:47 回复(0)
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        input.sort()
        return [input[i] for i in range(k)]

发表于 2022-04-23 11:38:19 回复(0)
Python
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        input.sort()
        for i in range(0,len(input)):
            return input[:k]
发表于 2022-03-10 15:37:09 回复(0)
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        def heapfiy(array, index, length):
            left = 2 * index + 1
            right = 2 * index + 2
            temp = index
            if left < length and array[temp] < array[left]:
                temp = left
            if right < length and array[temp] < array[right]:
                temp = right
            if temp != index:
                array[index], array[temp] = array[temp], array[index]
                heapfiy(array, temp, length)
        for i in range((k - 1) // 2, -1, -1):
            heapfiy(input, i, k)
        for i in range(k, len(input)):
            if input[i] < input[0]:
                input[i], input[0] = input[0], input[i]
                heapfiy(input, 0, k)
        return input[:k]
最大堆
发表于 2022-03-08 21:06:44 回复(0)